---
title: Kubernetes Deployment
description: Deploy Terrateam Self-Hosted on Kubernetes using Helm charts for GitHub and GitLab.
---

import { Steps, Tabs, TabItem } from '@astrojs/starlight/components';

Kubernetes deployment with Helm provides a production-ready, scalable solution for Terrateam Self-Hosted. This method is recommended for enterprise environments requiring high availability and automatic scaling, and supports both GitHub and GitLab.

:::caution[Required First Step]
You must run the Terrateam Setup application first to create your GitHub App or GitLab configuration. This generates the credentials needed for any deployment method (Docker, Kubernetes, or Manual).

**Run the setup wizard:**
```sh
git clone https://github.com/terrateamio/terrateam.git
cd terrateam/docker/terrat
docker-compose up setup
# Open http://localhost:3000 and complete the wizard
```
This creates a `.env` file with all required credentials.
:::

## Prerequisites

Before you begin, ensure you have:
- **Completed the Setup Wizard** (see above) to generate credentials
- **Kubernetes cluster**
- **Helm** installed
- **kubectl** configured to access your cluster

## Installation Steps

<Tabs>
<TabItem label="GitHub">

<Steps>

1. **Source your GitHub Application settings**

   Load the credentials generated by the Setup Wizard:

   ```sh
   # From the terrateam/docker/terrat directory
   source ./dotenv && .env export
   ```

2. **Create Kubernetes secrets for GitHub App**

   Create secrets for your private Terrateam GitHub Application:

   ```sh
   kubectl create secret generic terrateam-github-app-pem \
     --from-literal=pem="$GITHUB_APP_PEM"
   
   kubectl create secret generic terrateam-github-webhook-secret \
     --from-literal=secret="$GITHUB_WEBHOOK_SECRET"
   
   kubectl create secret generic terrateam-github-app-client-secret \
     --from-literal=secret="$GITHUB_APP_CLIENT_SECRET"
   
   kubectl create secret generic terrateam-github-app-client-id \
     --from-literal=id="$GITHUB_APP_CLIENT_ID"
   
   kubectl create secret generic terrateam-github-app-id \
     --from-literal=id="$GITHUB_APP_ID"
   ```

3. **Create database password secret**

   ```sh
   kubectl create secret generic terrateam-db-password \
     --from-literal=password="STRONG_PASSWORD_HERE"
   ```

   :::danger[Security]
   Replace `STRONG_PASSWORD_HERE` with a secure, randomly generated password.
   :::

4. **Add Terrateam Helm repository**

   ```sh
   helm repo add terrateamio https://terrateamio.github.io/helm-charts/
   helm repo update
   ```

   :::tip[Customization]
   View the Helm chart source and all available configuration options on [GitHub](https://github.com/terrateamio/helm-charts/tree/main/charts/terrateam).
   :::

5. **Choose your deployment configuration**

   Select one of the deployment options below based on your infrastructure.

</Steps>

</TabItem>
<TabItem label="GitLab">

<Steps>

1. **Source your GitLab configuration**

   Load the credentials generated by the Setup Wizard:

   ```sh
   # From the terrateam/docker/terrat directory
   source ./dotenv && .env export
   ```

2. **Create Kubernetes secrets for GitLab**

   Create secrets for your GitLab configuration:

   ```sh
   kubectl create secret generic terrateam-gitlab-app-id \
     --from-literal=id="$GITLAB_APP_ID"
   
   kubectl create secret generic terrateam-gitlab-app-secret \
     --from-literal=secret="$GITLAB_APP_SECRET"
   
   kubectl create secret generic terrateam-gitlab-access-token \
     --from-literal=token="$GITLAB_ACCESS_TOKEN"
   ```

3. **Create database password secret**

   ```sh
   kubectl create secret generic terrateam-db-password \
     --from-literal=password="STRONG_PASSWORD_HERE"
   ```

   :::danger[Security]
   Replace `STRONG_PASSWORD_HERE` with a secure, randomly generated password.
   :::

4. **Add Terrateam Helm repository**

   ```sh
   helm repo add terrateamio https://terrateamio.github.io/helm-charts/
   helm repo update
   ```

   :::tip[Customization]
   View the Helm chart source and all available configuration options on [GitHub](https://github.com/terrateamio/helm-charts/tree/main/charts/terrateam).
   :::

5. **Choose your deployment configuration**

   Select one of the deployment options below based on your infrastructure.

</Steps>

</TabItem>
<TabItem label="Enterprise Edition">

<Steps>

1. **Identify your enterprise image**

   Terrateam will provide you with a specific container image URL for the Enterprise Edition. This image includes additional features and enterprise-level support.

2. **Follow GitHub or GitLab setup steps**

   Complete steps 1-4 from either the GitHub or GitLab tab above to:
   - Source your application settings
   - Create Kubernetes secrets
   - Create database password secret
   - Add Terrateam Helm repository

3. **Deploy with enterprise image**

   You can override the default image using any of these methods:

   **Method 1: Command-line flags**

   Add image configuration flags to your helm install command:

   ```sh
   helm install terrateam terrateamio/terrateam \
     --set terrateam.image.repository="<terrateam-enterprise-docker-image-url>" \
     --set terrateam.image.tag="<image-tag>" \
     --set terrateam.image.pullPolicy="IfNotPresent" \
     --set terrateam.config.fqdn="terrateam.example.com" \
     # ... add other configuration flags as needed
   ```

   **Method 2: Values file**

   Create a file named `values.yaml`:

   ```yaml
   terrateam:
     image:
       repository: <terrateam-enterprise-docker-image-url>
       tag: <image-tag>
       pullPolicy: IfNotPresent
     config:
       fqdn: terrateam.example.com
       # Add other configuration as needed
   ```

   Then deploy using the values file:

   ```sh
   helm install terrateam terrateamio/terrateam -f values.yaml
   ```

3. **Choose your deployment configuration**

   After configuring the enterprise image, proceed to the Deployment Options section below to complete your setup based on your infrastructure.

</Steps>

</TabItem>
</Tabs>

## Deployment Options

### GKE with HTTPS Load Balancer

For Google Kubernetes Engine with managed SSL certificates:

<Steps>

1. **Create a global static IP address:**
   ```sh
   gcloud compute addresses create terrateam-static-ip --global
   ```

2. **Get the IP address:**
   ```sh
   gcloud compute addresses describe terrateam-static-ip --global
   ```

3. **Configure DNS**
   
   Add the static IP to your DNS zone as `terrateam.example.com`

4. **Install with Helm**
   
   Choose the appropriate command for your platform below.

</Steps>

<Tabs>
<TabItem label="GitHub.com">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.vcs="github" \
  --set terrateam.config.github.appUrl="$GITHUB_APP_URL" \
  --set terrateam.config.uiBase="https://terrateam.example.com" \
  --set ingress.certificate.enabled="true" \
  --set ingress.enabled="true" \
  --set ingress.className="gce" \
  --set ingress.annotations."networking\.gke\.io/managed-certificates"="terrateam-ingress-certificate" \
  --set ingress.annotations."kubernetes\.io/ingress\.global-static-ip-name"="terrateam-static-ip" \
  --set-string ingress.annotations."kubernetes\.io/ingress\.allow-http"="false"
```

</TabItem>
<TabItem label="GitHub Enterprise">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.vcs="github" \
  --set terrateam.config.github.apiBaseUrl="https://api.github.example.com" \
  --set terrateam.config.github.webBaseUrl="https://github.example.com" \
  --set terrateam.config.github.appUrl="$GITHUB_APP_URL" \
  --set terrateam.config.uiBase="https://terrateam.example.com" \
  --set ingress.certificate.enabled="true" \
  --set ingress.enabled="true" \
  --set ingress.className="gce" \
  --set ingress.annotations."networking\.gke\.io/managed-certificates"="terrateam-ingress-certificate" \
  --set ingress.annotations."kubernetes\.io/ingress\.global-static-ip-name"="terrateam-static-ip" \
  --set-string ingress.annotations."kubernetes\.io/ingress\.allow-http"="false"
```

</TabItem>
<TabItem label="GitLab.com">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.enabled=false \
  --set terrateam.config.gitlab.enabled=true \
  --set terrateam.config.uiBase="https://terrateam.example.com" \
  --set ingress.certificate.enabled="true" \
  --set ingress.enabled="true" \
  --set ingress.className="gce" \
  --set ingress.annotations."networking\.gke\.io/managed-certificates"="terrateam-ingress-certificate" \
  --set ingress.annotations."kubernetes\.io/ingress\.global-static-ip-name"="terrateam-static-ip" \
  --set-string ingress.annotations."kubernetes\.io/ingress\.allow-http"="false"
```

</TabItem>
<TabItem label="GitLab Self-Hosted">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.enabled=false \
  --set terrateam.config.gitlab.enabled=true \
  --set terrateam.config.gitlab.apiBaseUrl="https://gitlab.example.com/api" \
  --set terrateam.config.gitlab.webBaseUrl="https://gitlab.example.com" \
  --set terrateam.config.uiBase="https://terrateam.example.com" \
  --set ingress.certificate.enabled="true" \
  --set ingress.enabled="true" \
  --set ingress.className="gce" \
  --set ingress.annotations."networking\.gke\.io/managed-certificates"="terrateam-ingress-certificate" \
  --set ingress.annotations."kubernetes\.io/ingress\.global-static-ip-name"="terrateam-static-ip" \
  --set-string ingress.annotations."kubernetes\.io/ingress\.allow-http"="false"
```

</TabItem>
</Tabs>

:::note[Certificate Provisioning]
Google-managed SSL certificates with Ingress can take up to 60 minutes to configure. The Ingress may show as ready while the certificate is still provisioning.
:::

### Without Ingress

For clusters without ingress controllers:

<Tabs>
<TabItem label="GitHub.com">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.appUrl="$GITHUB_APP_URL" \
  --set terrateam.config.uiBase="https://terrateam.example.com"
```

</TabItem>
<TabItem label="GitHub Enterprise">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.apiBaseUrl="https://api.github.example.com" \
  --set terrateam.config.github.webBaseUrl="https://github.example.com" \
  --set terrateam.config.github.appUrl="$GITHUB_APP_URL" \
  --set terrateam.config.uiBase="https://terrateam.example.com"
```

</TabItem>
<TabItem label="GitLab.com">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.enabled=false \
  --set terrateam.config.gitlab.enabled=true \
  --set terrateam.config.uiBase="https://terrateam.example.com"
```

</TabItem>
<TabItem label="GitLab Self-Hosted">

```sh
helm install terrateam terrateamio/terrateam \
  --set terrateam.config.fqdn="terrateam.example.com" \
  --set terrateam.config.github.enabled=false \
  --set terrateam.config.gitlab.enabled=true \
  --set terrateam.config.gitlab.apiBaseUrl="https://gitlab.example.com/api" \
  --set terrateam.config.gitlab.webBaseUrl="https://gitlab.example.com" \
  --set terrateam.config.uiBase="https://terrateam.example.com"
```

</TabItem>
</Tabs>

You can later expose the `terrateam-server` service using:
- [NGINX Ingress Controller](https://cert-manager.io/docs/tutorials/acme/nginx-ingress/)
- [cert-manager](https://github.com/cert-manager/cert-manager) for SSL certificates

## Configure Webhook URLs

<Tabs>
<TabItem label="GitHub">

For GitHub, you need to configure the webhook URL in your GitHub App settings:

1. Navigate to your GitHub App settings page (find the URL in your `.env` file)
2. Go to the "General" tab
3. In the "Webhook" section, set the URL to: `https://terrateam.example.com/api/github/v1/events`
4. Ensure the webhook secret matches the one you configured during setup
5. Save your changes

:::note[Webhook Path]
Always include the trailing `/api/github/v1/events` path for GitHub webhooks.
:::

</TabItem>
<TabItem label="GitLab">

For GitLab, you'll need to configure webhooks in your GitLab projects:

1. Navigate to your GitLab project settings
2. Go to Settings → Webhooks
3. Add webhook URL: `https://terrateam.example.com/api/gitlab/v1/events`
4. Select the following events:
   - Push events
   - Merge request events
   - Comments
   - Pipeline events

</TabItem>
</Tabs>

## Enable Terrateam UI Access

<Tabs>
<TabItem label="GitHub">

To enable the Terrateam web UI for GitHub:

1. Navigate to your GitHub App settings (e.g., `https://github.com/apps/your-terrateam-app`)
2. Click on "App settings" on the right side under the Install button
3. Check the box "Request user authorization (OAuth) during installation"
4. Set the callback URL to: `https://terrateam.example.com/api/github/v1/callback`
5. Save your changes

:::note[OAuth Callback]
The callback URL must match your deployment's FQDN with the path `/api/github/v1/callback`
:::

</TabItem>
<TabItem label="GitLab">

To access the Terrateam web UI for GitLab:

1. Ensure your GitLab Personal Access Token is configured with the required scopes
2. The UI access is already enabled through the OAuth configuration during setup

</TabItem>
</Tabs>

## Getting Started Wizard

Once you've enabled UI access, the next step is to complete the Getting Started Wizard:

1. **Access the Terrateam UI**
   - Navigate to: `https://terrateam.example.com`
   - Log in with your GitHub or GitLab account

2. **Complete the Getting Started Wizard**
   
   The wizard will guide you through:
   - **Repository/Project Selection**: Choose which repositories (GitHub) or projects (GitLab) to enable for Terrateam
   - **Cloud Provider Configuration**: Set up credentials for AWS, GCP, Azure, or other cloud providers
   - **Workflow Setup**: Configure your first Terraform workflows and apply requirements
   - **Team Permissions**: Set up role-based access control if needed

3. **Verify Your Setup**
   - Create a test pull request or merge request
   - Confirm Terrateam responds with a plan
   - Apply your first change

## Production Management

This section covers essential tasks for managing your Terrateam deployment in production, including scaling, monitoring, maintenance, and troubleshooting.

### Scaling and High Availability

#### Horizontal Scaling

Scale the number of Terrateam server replicas:

```sh
helm upgrade terrateam terrateamio/terrateam \
  --set server.replicas=3
```

#### Database High Availability

For production workloads, consider:
- External managed PostgreSQL (AWS RDS, Google Cloud SQL, Azure Database)
- PostgreSQL cluster with automatic failover
- Regular database backups

### Monitoring and Logging

#### Health Checks

Terrateam provides health check endpoints:
- `/health` - Overall application health
- `/metrics` - Prometheus metrics (if enabled)

### Maintenance

#### Updates

Update to the latest Terrateam version:

```sh
helm repo update
helm upgrade terrateam terrateamio/terrateam
```

#### Rolling Restarts

Perform rolling restart without downtime:

```sh
kubectl rollout restart deployment/terrateam-server
```
